/*
 * test_bounds_check.c - Test cases for boundary checking functions
 */

#include "bounds_check.h"
#include <stdio.h>
#include <string.h>
#include <assert.h>

#define TEST_BUFFER_SIZE 32

void test_strcpy_s() {
    printf("Testing strcpy_s...\n");

    char dest[TEST_BUFFER_SIZE];
    const char *src = "Hello, World!";

    /* Test successful copy */
    int result = strcpy_s(dest, sizeof(dest), src);
    assert(result == BOUNDS_CHECK_SUCCESS);
    assert(strcmp(dest, src) == 0);

    /* Test buffer too small */
    char small_dest[5];
    result = strcpy_s(small_dest, sizeof(small_dest), src);
    assert(result == BOUNDS_CHECK_BUFFER_TOO_SMALL);
    assert(small_dest[0] == '\0');

    /* Test invalid parameters */
    result = strcpy_s(NULL, sizeof(dest), src);
    assert(result == BOUNDS_CHECK_INVALID_PARAM);

    result = strcpy_s(dest, 0, src);
    assert(result == BOUNDS_CHECK_INVALID_PARAM);

    result = strcpy_s(dest, sizeof(dest), NULL);
    assert(result == BOUNDS_CHECK_INVALID_PARAM);

    printf("  strcpy_s tests passed!\n");
}

void test_strncpy_s() {
    printf("Testing strncpy_s...\n");

    char dest[TEST_BUFFER_SIZE];
    const char *src = "Hello, World!";

    /* Test successful copy */
    int result = strncpy_s(dest, sizeof(dest), src, 5);
    assert(result == BOUNDS_CHECK_SUCCESS);
    assert(strcmp(dest, "Hello") == 0);

    /* Test buffer too small */
    char small_dest[3];
    result = strncpy_s(small_dest, sizeof(small_dest), src, 5);
    assert(result == BOUNDS_CHECK_BUFFER_TOO_SMALL);
    assert(small_dest[0] == '\0');

    printf("  strncpy_s tests passed!\n");
}

void test_strcat_s() {
    printf("Testing strcat_s...\n");

    char dest[TEST_BUFFER_SIZE] = "Hello, ";
    const char *src = "World!";

    /* Test successful concatenation */
    int result = strcat_s(dest, sizeof(dest), src);
    assert(result == BOUNDS_CHECK_SUCCESS);
    assert(strcmp(dest, "Hello, World!") == 0);

    /* Test buffer too small */
    char small_dest[10] = "Hello, ";
    result = strcat_s(small_dest, sizeof(small_dest), "World!");
    assert(result == BOUNDS_CHECK_BUFFER_TOO_SMALL);
    assert(strcmp(small_dest, "Hello, ") == 0);

    printf("  strcat_s tests passed!\n");
}

void test_memcpy_s() {
    printf("Testing memcpy_s...\n");

    char dest[TEST_BUFFER_SIZE];
    char src[] = "Test data";

    /* Test successful copy */
    int result = memcpy_s(dest, sizeof(dest), src, sizeof(src));
    assert(result == BOUNDS_CHECK_SUCCESS);
    assert(memcmp(dest, src, sizeof(src)) == 0);

    /* Test buffer too small */
    char small_dest[5];
    result = memcpy_s(small_dest, sizeof(small_dest), src, sizeof(src));
    assert(result == BOUNDS_CHECK_BUFFER_TOO_SMALL);

    printf("  memcpy_s tests passed!\n");
}

void test_memset_s() {
    printf("Testing memset_s...\n");

    char buffer[TEST_BUFFER_SIZE];

    /* Test successful memset */
    int result = memset_s(buffer, sizeof(buffer), 'A', 10);
    assert(result == BOUNDS_CHECK_SUCCESS);

    for (int i = 0; i < 10; i++) {
        assert(buffer[i] == 'A');
    }

    /* Test buffer too small */
    char small_buffer[5];
    result = memset_s(small_buffer, sizeof(small_buffer), 'B', 10);
    assert(result == BOUNDS_CHECK_BUFFER_TOO_SMALL);

    printf("  memset_s tests passed!\n");
}

void test_strnlen_s() {
    printf("Testing strnlen_s...\n");

    const char *str = "Hello";
    size_t len;

    /* Test successful length calculation */
    int result = strnlen_s(str, 10, &len);
    assert(result == BOUNDS_CHECK_SUCCESS);
    assert(len == 5);

    /* Test bounded length calculation */
    result = strnlen_s(str, 3, &len);
    assert(result == BOUNDS_CHECK_SUCCESS);
    assert(len == 3);

    /* Test invalid parameters */
    result = strnlen_s(NULL, 10, &len);
    assert(result == BOUNDS_CHECK_INVALID_PARAM);

    result = strnlen_s(str, 10, NULL);
    assert(result == BOUNDS_CHECK_INVALID_PARAM);

    printf("  strnlen_s tests passed!\n");
}

void test_check_buffer() {
    printf("Testing check_buffer...\n");

    char buffer[TEST_BUFFER_SIZE];

    /* Test valid buffer */
    int result = check_buffer(buffer, sizeof(buffer));
    assert(result == BOUNDS_CHECK_SUCCESS);

    /* Test invalid buffer */
    result = check_buffer(NULL, sizeof(buffer));
    assert(result == BOUNDS_CHECK_INVALID_PARAM);

    result = check_buffer(buffer, 0);
    assert(result == BOUNDS_CHECK_INVALID_PARAM);

    printf("  check_buffer tests passed!\n");
}

int main() {
    printf("Running boundary checking function tests...\n\n");

    test_strcpy_s();
    test_strncpy_s();
    test_strcat_s();
    test_memcpy_s();
    test_memset_s();
    test_strnlen_s();
    test_check_buffer();

    printf("\nAll tests passed!\n");
    return 0;
}